#include <Kernel/WE.h>
#include <Kernel/TS.h>

// 引用Windows头文件
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif // WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <iostream>
#include <Core.h>
#include <array>

#include <sstream>

static const std::array<char, 1612> gCopyRightString{R"(
版权所有Copy Right:
        blbl: 是柱柱啊-

使用说明：
1.TS
        - 在奔跑滑铲跳时,转动视角,即可向视角方向进行TS
        - 提示: 确保"W" + "Crrl" + "空格"同时按下>_<

2.WE
        - 模拟滚轮E,甚至比滚轮按下E的频率更高
        - 按下鼠标侧边按键即可,不影响Apex键位绑定

3.JUMP
		- 兔子跳,双击鼠标侧边按键即可,不影响Apex键位绑定
#########################################################################
#######                         ##########                        #######
#######                         ##########                        #######
################       ###################     ##########################
################       ###################     ##########################
################       ###################     ##########################
################       ###################     ##########################
################       ###################                        #######
################       ###################                        #######
################       ######################################     #######
################       ######################################     #######
################       ######################################     #######
################       ######################################     #######
################       ###################                        #######
################       ###################                        #######
#########################################################################
)"};

/*
1  - January
2  - February
3  - March
4  - April
5  - May
6  - June
7  - July
8  - August
9  - September
10 - October
11 - November
12 - December
*/

static const char *gCompilerInfo = "Compiler Date: " __DATE__ " | " __TIME__ "\n";

static const char *gCopyRightInfo = R"(Copyright And Developed by 'LiangZhu'
Email : 1516503671@qq.com
)";

static const char *gTitle = u8R"(
          _____                      _____                      _____
         /\    \                    /\    \                    /\    \                   ______ 
        /::\    \                  /::\    \                  /::\    \                 |::|   |
       /::::\    \                /::::\    \                /::::\    \                |::|   |
      /::::::\    \              /::::::\    \              /::::::\    \               |::|   |
     /:::/\:::\    \            /:::/\:::\    \            /:::/\:::\    \              |::|   |
    /:::/__\:::\    \          /:::/__\:::\    \          /:::/__\:::\    \             |::|   |
   /::::\   \:::\    \        /::::\   \:::\    \        /::::\   \:::\    \            |::|   |
  /::::::\   \:::\    \      /::::::\   \:::\    \      /::::::\   \:::\    \           |::|   |
 /:::/\:::\   \:::\    \    /:::/\:::\   \:::\____\    /:::/\:::\   \:::\    \    ______|::|___|___ ____ 
/:::/  \:::\   \:::\____\  /:::/  \:::\   \:::|    |  /:::/__\:::\   \:::\____\  |:::::::::::::::::|    |
\::/    \:::\  /:::/    /  \::/    \:::\  /:::|____|  \:::\   \:::\   \::/    /  |______::::___:___|____|
 \/____/ \:::\/:::/    /    \/_____/\:::\/:::/    /    \:::\   \:::\   \/____/          |::|   |
          \::::::/    /              \::::::/    /      \:::\   \:::\    \              |::|   |
           \::::/    /                \::::/    /        \:::\   \:::\____\             |::|   |
           /:::/    /                  \__/____/          \:::\   \::/    /             |::|   |
          /:::/    /                                       \:::\   \/____/              |::|   |
         /:::/    /                                         \:::\    \                  |::|   |
        /:::/    /                                           \:::\____\                 |::|   |
        \::/    /                                             \::/    /                 |__|___|
         \/____/                                               \/____/
)";

static uint32_t gTableWidth = 0x10;

struct TableStyle
{
    char HozSybo = '-';
    char PointSybo = '+';
    char VerSybo = '|';
};

struct TableLine
{
    const char **mCellDatas;
    uint32_t mCellCount;
};

struct TableData
{
    TableLine *mData;
    uint32_t mLineCount;
};

struct TableContext
{
    uint32_t mCellExtensionCount;
    std::array<size_t, 0x10> mCellWidths;
    std::array<char, 0x10000> mRenderBuffer;
};

struct RenderTempBuffer
{
    std::array<char, 0x1000> mSpliterBuffer;
    size_t mSpliterCount;
};

#define CHECK_MAX(a, b) ((a) > (b) ? (a) : (b))

static void RenderTable(const TableStyle &style, const TableData &data, TableContext &ctx)
{
    uint32_t localCellCount = 0x0;
    RenderTempBuffer localTB{};
    uint32_t localWriteOffset = 0x0;
    RenderTempBuffer localVerticalBuf{};

    for (uint32_t idx = 0x0; idx < data.mLineCount; ++idx)
    {
        const TableLine &line = data.mData[idx];
        localCellCount = CHECK_MAX(line.mCellCount, localCellCount);

        for (uint32_t i = 0x0; i < line.mCellCount; ++i)
        {
            const size_t localCurrentCellWidth = static_cast<size_t>(strlen(line.mCellDatas[i]));
            ctx.mCellWidths[i] = CHECK_MAX(localCurrentCellWidth, ctx.mCellWidths[i]);
        }
    }

    localTB.mSpliterCount = static_cast<size_t>(localCellCount + 0x2); //
    for (uint32_t idx = 0x0; idx < localCellCount; ++idx)
    {
        localTB.mSpliterCount += ctx.mCellWidths[idx];
    }

    localVerticalBuf.mSpliterCount = localTB.mSpliterCount;

    memset(localTB.mSpliterBuffer.data(), style.PointSybo, localTB.mSpliterCount);
    memset(localVerticalBuf.mSpliterBuffer.data(), style.VerSybo, localVerticalBuf.mSpliterCount);

    size_t localLineCurPoint = 0x0;
    for (uint32_t idx = 0x0; idx < localCellCount; ++idx)
    {
        const uint32_t localPointOffset = idx + 0x1;
        memset(&localTB.mSpliterBuffer[localLineCurPoint + localPointOffset], style.HozSybo, ctx.mCellWidths[idx]);
        memset(&localVerticalBuf.mSpliterBuffer[localLineCurPoint + localPointOffset], ' ', ctx.mCellWidths[idx]);
        localLineCurPoint += ctx.mCellWidths[idx];
    }

    localTB.mSpliterBuffer[localTB.mSpliterCount - 0x1] = '\n';
    localVerticalBuf.mSpliterBuffer[localVerticalBuf.mSpliterCount - 0x1] = '\n';

    for (uint32_t idx = 0x0; idx < data.mLineCount; ++idx)
    {
        memcpy(&ctx.mRenderBuffer[localWriteOffset], localTB.mSpliterBuffer.data(), localTB.mSpliterCount);
        localWriteOffset += static_cast<size_t>(localTB.mSpliterCount);
        const size_t localCurrentOffset = localWriteOffset;
        memcpy(&ctx.mRenderBuffer[localWriteOffset], localVerticalBuf.mSpliterBuffer.data(), localVerticalBuf.mSpliterCount);
        localWriteOffset += static_cast<size_t>(localVerticalBuf.mSpliterCount);

        const TableLine &line = data.mData[idx];
        uint32_t localBeginOffset = 0x0;
        for (uint32_t i = 0x0; i < line.mCellCount; ++i)
        {
            const uint32_t localPointOffset = i + 0x1;
            const size_t localDataLength = static_cast<size_t>(strlen(line.mCellDatas[i]));
            memcpy(&ctx.mRenderBuffer[localCurrentOffset + localBeginOffset + localPointOffset], line.mCellDatas[i], localDataLength);

            localBeginOffset += static_cast<size_t>(ctx.mCellWidths[i]);
        }
    }

    memcpy(&ctx.mRenderBuffer[localWriteOffset], localTB.mSpliterBuffer.data(), localTB.mSpliterCount);
    localWriteOffset += static_cast<size_t>(localTB.mSpliterCount);
}

/*
+-+------------+
|a|            |            |
+-+-----------+------------+
|             |            |
+-------------+------------+
|             |            |
+-------------+------------+
|             |            |
+-------------+------------+
|             |            |
+-------------+------------+
*/

int main()
{
    std::cout << &gTitle[0x1];
    
    std::array<const char *, 0x2> CompilerInfo{
        "Compiler Date",
        __DATE__ " - " __TIME__
    };

    std::array<const char *, 0x2> AuthorInfo{
        "Author",
        "Liang-Zhu"
    };

    std::array<const char *, 0x2> EmailInfo{
        "Email",
        "1516503671@qq.com"
    };

    std::array<TableLine, 0x3> localShowData;
    {
        TableLine &line = localShowData[0x0];
        line.mCellCount = CompilerInfo.size();
        line.mCellDatas = CompilerInfo.data();
    }
    {
        TableLine &line = localShowData[0x1];
        line.mCellCount = AuthorInfo.size();
        line.mCellDatas = AuthorInfo.data();
    }
    {
        TableLine &line = localShowData[0x2];
        line.mCellCount = EmailInfo.size();
        line.mCellDatas = EmailInfo.data();
    }

    const TableData localData{localShowData.data(),static_cast<uint32_t>(localShowData.size())};

    static TableContext ctx{};
    ctx.mRenderBuffer.fill(0x0);
    RenderTable({},localData,ctx);

    std::cout << ctx.mRenderBuffer.data();

    // DecodePart(begin, end, bufferBegin, &localBuffer[8000]);
    TS::GetInstance().Start();
    WE::Start();
    MSG msg{};
    return GetMessageW(&msg, nullptr, 0, 0);
}